package cn.bbstone.e4.ui.log.parts;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.di.UIEventTopic;
import org.eclipse.e4.ui.di.UISynchronize;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.swt.widgets.Composite;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.spi.ILoggingEvent;
import cn.bbstone.e4.ui.log.appender.E4LogbackAppender;
import cn.bbstone.e4.ui.log.event.LogPartEvents;
import cn.bbstone.e4.ui.log.service.LogsService;
import cn.bbstone.e4.ui.log.views.LogsIOConsole;
import cn.bbstone.e4.ui.log.views.LogsIOConsoleViewer;

public class LogsPart {
	private static Logger log = LoggerFactory.getLogger(LogsPart.class);

	@Inject
	UISynchronize sync;
	@Inject
	IEventBroker eventBroker;
	
	@Inject
	private LogsService logsService;
	
//	@Inject
	private E4LogbackAppender<ILoggingEvent> e4LogbackAppender;
	
	private LogsIOConsole ioConsole;
	private LogsIOConsoleViewer consoleViewer;

	private boolean lockConsole = false;
	@Inject // Display display, WorkbenchAdvisor advisor,
	public LogsPart(MApplication app, IEclipseContext appContext) {
//		this.e4LogbackAppender = (E4LogbackAppender<ILoggingEvent>) appContext.get(E4LogbackAppender.class.getName());
//		ServiceReference<?> ref = Activator.getServiceReference(E4LogbackAppender.class);
//		this.e4LogbackAppender = (E4LogbackAppender<ILoggingEvent>)Activator.get.getService(ref);
		
		BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
		@SuppressWarnings("rawtypes")
		ServiceReference<E4LogbackAppender> logser = bundleContext.getServiceReference(E4LogbackAppender.class);
		@SuppressWarnings("unchecked")
		E4LogbackAppender<ILoggingEvent> e4LogAppender = bundleContext.getService(logser);
        this.e4LogbackAppender = e4LogAppender;
        
		log.info((this.getClass().getSimpleName() + " constructed"));
	}

	@PostConstruct
	public void createControls(Composite parent) {
		log.info(this.getClass().getSimpleName() + " @PostConstruct method called.");
		
		ioConsole = new LogsIOConsole(sync, "cn.bbstone.pisces2.logconsole", null);
		consoleViewer = new LogsIOConsoleViewer(parent, ioConsole, sync);
		consoleViewer.setWordWrap(true);
		consoleViewer.setAutoScroll(true);
		consoleViewer.setConsoleAutoScrollLock(lockConsole);
		
		logsService.setLogConsole(ioConsole);
		logsService.setLogOutputStream(ioConsole.newOutputStream());
		logsService.setEventBroker(eventBroker);
		
		// NOTICE: need logsService.getLogOutputStream() for appender to start up e4LogbackAppender
		e4LogbackAppender.setLogsService(logsService);
		e4LogbackAppender.start();

//		oputs = ioConsole.newOutputStream();
//		logsPartView.setOputs(oputs);
		// Case: 1
//		text = new Text(parent, SWT.READ_ONLY | SWT.MULTI);
//		OutputStream oputs = new OutputStream() {
//			@Override
//			public void write(int b) throws IOException {
//				if (text.isDisposed())
//					return;
//				text.append(String.valueOf((char) b));
//			}
//		};
//		final PrintStream oldOut = System.out;
//		System.setOut(new PrintStream(oputs));
//		text.addDisposeListener(new DisposeListener() {
//			public void widgetDisposed(DisposeEvent e) {
//				System.setOut(oldOut);
//			}
//		});
		// Case: 2
//		part.getToolbar().
//		IActionBars actionBars = trimBar.get.getActionBars();
//		// 隐藏视图菜单
//		IMenuManager menuManager = actionBars.getMenuManager();
//		menuManager.setVisible(false);
//		// 隐藏工具条按钮
//		IToolBarManager toolBarManager = actionBars.getToolBarManager();
//		IContributionItem[] items = toolBarManager.getItems();
//		for(IContributionItem item: items) {
//			item.setVisible(false);
//		}
//		// 更新视图菜单
//		actionBars.updateActionBars();

	}

	@Focus
	public void setFocus() {
//		text.setFocus();
	}

	@PreDestroy
	public void dispose() {
		if (ioConsole != null) {
			// required: close console output stream 
			ioConsole.dispose();
		}
		if (consoleViewer != null) {
			// required: cancel revealJobx
			consoleViewer.dispose();
		}
	}
	
	@Inject @Optional
	void clickClear(final @UIEventTopic(LogPartEvents.CLEAR_CO) String message) {
//		consoleViewer.cl
	}
	
	@Inject @Optional
	void clickWordWrap(final @UIEventTopic(LogPartEvents.WORD_WRAP) String message) {
		if (consoleViewer.isWordWrap()) {
			consoleViewer.setWordWrap(false);
			consoleViewer.refresh();
		} else {
			this.consoleViewer.setWordWrap(true);
			consoleViewer.refresh();
		}
	}
	
	@Inject @Optional
	void clickLock(final @UIEventTopic(LogPartEvents.LOCK_CO) String message) {
		if (lockConsole) { // TODO maybe can used TextConsole.isConsoleAutoScrollLock()
			consoleViewer.setConsoleAutoScrollLock(false);
			consoleViewer.refresh();
			lockConsole = false;
		} else {
			consoleViewer.setConsoleAutoScrollLock(true);
			consoleViewer.refresh();
			lockConsole = true;
		}
	}
	

}
